import { IPoint } from "@/models/gui";
import { IFn } from "@/models/math";

// 二次样条插值, points.length >= 2
export function getQuadSplineFn (points: IPoint[], z0 = 1): IFn {
  const Z: number[] = [z0];
  const X = points.map(o => o.x);
  const Y = points.map(o => o.y);
  points.forEach((p, i) => {
    if (i > 0) {
      const z = - Z[i-1] + 2 * (Y[i] - Y[i-1]) / (X[i] - X[i-1]);
      Z.push(z);
    }
  });
  const S: IFn[] = [];
  Z.forEach((z, i) => {
    if (i == Z.length - 1) {
      return;
    }
    const fn: IFn = (x) => Y[i] + Z[i] * (x - X[i]) + (Z[i+1] - Z[i]) * (x - X[i]) * (x - X[i]) / 2 / (X[i+1] - X[i]);
    S.push(fn);
  });
  return (x) => {
    if (x < X[0]) {
      return S[0](x);
    }
    for (let i = 0; i < X.length - 1; i++) {
      if (x >= X[i] && x <= X[i + 1]) {
        return S[i](x);
      }
    }
    return S[S.length - 1](x);
  };
}
